#include "frmdeviceconfig.h"
#include <QMessageBox>
#include <QThread>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QTextEdit>
#include <QTcpSocket>
#include <QSerialPort>

frmdeviceconfig::frmdeviceconfig(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::frmdeviceconfig),
    mainWindow(qobject_cast<frmmain*>(parent)),
    isSettingMode(false),
    isWaitingForNtripConfig(false),
    lastCommand("")
{
    ui->setupUi(this);

    if (!mainWindow) {
        updateMainResponse("错误：无法获取主窗口指针");
    }

    // 初始化控件状态
    ui->exitSettingModeButton->setEnabled(false);
    enableConfigControls(false);

    // 初始时根据连接状态设置按钮
    updateSettingModeButtonState();

    // 设置超时定时器
    responseTimer.setSingleShot(true);
    connect(&responseTimer, &QTimer::timeout, this, &frmdeviceconfig::onResponseTimeout);

    // 连接 frmmain 的信号以动态更新按钮状态和接收数据
    if (mainWindow) {
        connect(mainWindow, &frmmain::serialConnectionChanged, this, &frmdeviceconfig::onSerialConnectionChanged);
        connect(mainWindow, &frmmain::tcpConnectionChanged, this, &frmdeviceconfig::onTcpConnectionChanged);
        connect(mainWindow, &frmmain::serialDataReceived, this, &frmdeviceconfig::onSerialDataReceived); // 新增
        connect(mainWindow, &frmmain::tcpDataReceived, this, &frmdeviceconfig::onTcpDataReceived);       // 新增
    }
}

frmdeviceconfig::~frmdeviceconfig()
{
    delete ui;
}

void frmdeviceconfig::on_enterSettingModeButton_clicked()
{
    if (!mainWindow) {
        updateMainResponse("错误：主窗口指针无效");
        return;
    }

    if (!mainWindow->getIsTcpConnected() && !mainWindow->getIsSerialConnected()) {
        updateMainResponse("错误：请先建立 TCP 或串口连接");
        return;
    }

    sendSettingModeCommand(true);
    isSettingMode = true;
    ui->enterSettingModeButton->setEnabled(false);
    ui->exitSettingModeButton->setEnabled(true);
    enableConfigControls(true);
    updateMainResponse("已进入设置模式 ($CFG+)");
}

void frmdeviceconfig::on_exitSettingModeButton_clicked()
{
    if (!mainWindow) {
        updateMainResponse("错误：主窗口指针无效");
        return;
    }

    if (!mainWindow->getIsTcpConnected() && !mainWindow->getIsSerialConnected()) {
        updateMainResponse("错误：请先建立 TCP 或串口连接");
        return;
    }

    sendSettingModeCommand(false);
    isSettingMode = false;
    ui->enterSettingModeButton->setEnabled(true);
    ui->exitSettingModeButton->setEnabled(false);
    enableConfigControls(false);
    resetConfigFields();
    updateMainResponse("已退出设置模式 ($CFG-)");
}

void frmdeviceconfig::on_sendConfigButton_clicked()
{
    if (!mainWindow) {
        updateMainResponse("错误：主窗口指针无效");
        return;
    }

    if (!mainWindow->getIsTcpConnected() && !mainWindow->getIsSerialConnected()) {
        updateMainResponse("错误：请先建立 TCP 或串口连接");
        return;
    }

    if (!isSettingMode) {
        updateMainResponse("错误：请先进入设置模式");
        return;
    }

    // 获取 NTRIP 设置参数
    QString ntripIp = ui->ntripIpLineEdit->text().trimmed();
    QString ntripPort = ui->ntripPortLineEdit->text().trimmed();
    QString ntripMountPoint = ui->ntripMountPointLineEdit->text().trimmed();
    QString ntripUsername = ui->ntripUsernameLineEdit->text().trimmed();
    QString ntripPassword = ui->ntripPasswordLineEdit->text().trimmed();

    // 验证输入
    if (ntripIp.isEmpty() || ntripPort.isEmpty() || ntripMountPoint.isEmpty()) {
        updateMainResponse("错误：NTRIP IP 地址、端口和挂载点不能为空");
        return;
    }

    bool ok;
    int port = ntripPort.toInt(&ok);
    if (!ok || port <= 0 || port > 65535) {
        updateMainResponse("错误：NTRIP 端口号必须为 1-65535 之间的整数");
        return;
    }

    // 构造单一 NTRIP 配置命令
    QString command = QString("$NTRIP,%1,%2,%3,%4,%5\r\n")
                         .arg(ntripIp)
                         .arg(port)
                         .arg(ntripMountPoint)
                         .arg(ntripUsername)
                         .arg(ntripPassword);
    updateMainResponse("准备下发 NTRIP 配置...");

    // 通过串口或 TCP 发送命令
    bool useTcp = mainWindow->getIsTcpConnected();
    if (useTcp) {
        QTcpSocket *tcpSocket = mainWindow->getTcpSocket();
        if (tcpSocket->state() == QAbstractSocket::ConnectedState) {
            lastCommand = command.trimmed();
            tcpSocket->write(command.toUtf8());
            tcpSocket->flush();
            updateMainResponse("发送: " + command.trimmed());
            QThread::msleep(100);
            updateMainResponse("NTRIP 配置已通过网络发送，等待设备回复...");
        }
    } else {
        QSerialPort *serialPort = mainWindow->getSerialPort();
        if (serialPort->isOpen()) {
            lastCommand = command.trimmed();
            serialPort->write(command.toUtf8());
            serialPort->flush();
            updateMainResponse("发送: " + command.trimmed());
            QThread::msleep(100);
            updateMainResponse("NTRIP 配置已通过串口发送，等待设备回复...");
        }
    }

    // 下发完成后退出设置模式
    sendSettingModeCommand(false);
    isSettingMode = false;
    ui->enterSettingModeButton->setEnabled(true);
    ui->exitSettingModeButton->setEnabled(false);
    enableConfigControls(false);
}

void frmdeviceconfig::on_cancelButton_clicked()
{
    if (isSettingMode) {
        if (mainWindow && (mainWindow->getIsTcpConnected() || mainWindow->getIsSerialConnected())) {
            sendSettingModeCommand(false);
        }
        isSettingMode = false;
        ui->enterSettingModeButton->setEnabled(true);
        ui->exitSettingModeButton->setEnabled(false);
    }

    resetConfigFields();
    enableConfigControls(false);
    updateMainResponse("已取消操作，配置已重置");
}

void frmdeviceconfig::on_saveConfigButton_clicked()
{
    QJsonObject configObject;

    QJsonObject ntripConfig;
    ntripConfig["ip"] = ui->ntripIpLineEdit->text();
    ntripConfig["port"] = ui->ntripPortLineEdit->text();
    ntripConfig["mountPoint"] = ui->ntripMountPointLineEdit->text();
    ntripConfig["username"] = ui->ntripUsernameLineEdit->text();
    ntripConfig["password"] = ui->ntripPasswordLineEdit->text();
    configObject["ntrip"] = ntripConfig;

    QFile file("ntrip_config.json");
    if (!file.open(QIODevice::WriteOnly)) {
        updateMainResponse("错误：无法打开文件 ntrip_config.json 进行写入");
        return;
    }

    QJsonDocument doc(configObject);
    file.write(doc.toJson());
    file.close();

    updateMainResponse("配置已保存到 ntrip_config.json");
}

void frmdeviceconfig::on_loadConfigButton_clicked()
{
    if (!mainWindow) {
        updateMainResponse("错误：主窗口指针无效");
        return;
    }

    if (!mainWindow->getIsTcpConnected() && !mainWindow->getIsSerialConnected()) {
        updateMainResponse("错误：请先建立 TCP 或串口连接");
        return;
    }

    if (!isSettingMode) {
        updateMainResponse("错误：请先进入设置模式");
        return;
    }

    // 清空当前控件内容
    resetConfigFields();

    // 发送 NTRIP 配置查询指令
    sendNtripQueryCommand();
    isWaitingForNtripConfig = true;
    updateMainResponse("已发送 NTRIP 配置查询指令 ($NTRIP,?)，等待设备回复..."); // 修改：提示信息更正为 $NTRIP,?
    startResponseTimer();
}

void frmdeviceconfig::sendNtripQueryCommand()
{
    QString command = "$NTRIP,?\r\n";
    lastCommand = command.trimmed();
    bool useTcp = mainWindow->getIsTcpConnected();
    if (useTcp) {
        QTcpSocket *tcpSocket = mainWindow->getTcpSocket();
        if (tcpSocket->state() == QAbstractSocket::ConnectedState) {
            tcpSocket->write(command.toUtf8());
            tcpSocket->flush();
            updateMainResponse("发送: " + command.trimmed());
        } else {
            updateMainResponse("错误：TCP 连接无效");
            isWaitingForNtripConfig = false;
        }
    } else {
        QSerialPort *serialPort = mainWindow->getSerialPort();
        if (serialPort->isOpen()) {
            serialPort->write(command.toUtf8());
            serialPort->flush();
            updateMainResponse("发送: " + command.trimmed());
        } else {
            updateMainResponse("错误：串口连接无效");
            isWaitingForNtripConfig = false;
        }
    }
}

void frmdeviceconfig::onSerialConnectionChanged(bool connected)
{
    updateSettingModeButtonState();
}

void frmdeviceconfig::onTcpConnectionChanged(bool connected)
{
    updateSettingModeButtonState();
}

void frmdeviceconfig::updateSettingModeButtonState()
{
    bool isConnected = mainWindow && (mainWindow->getIsSerialConnected() || mainWindow->getIsTcpConnected());
    ui->enterSettingModeButton->setEnabled(isConnected && !isSettingMode);
    ui->exitSettingModeButton->setEnabled(isConnected && isSettingMode);
}

void frmdeviceconfig::sendSettingModeCommand(bool enter)
{
    if (!mainWindow) return;

    QString command = enter ? Config::enterConfigMode() : Config::exitConfigMode();
    if (mainWindow->getIsSerialConnected()) {
        QSerialPort *serialPort = mainWindow->getSerialPort();
        if (serialPort->isOpen()) {
            lastCommand = command.trimmed();
            serialPort->write(command.toUtf8());
            serialPort->flush();
        }
    }
    if (mainWindow->getIsTcpConnected()) {
        QTcpSocket *tcpSocket = mainWindow->getTcpSocket();
        if (tcpSocket->state() == QAbstractSocket::ConnectedState) {
            lastCommand = command.trimmed();
            tcpSocket->write(command.toUtf8());
            tcpSocket->flush();
        }
    }
}

void frmdeviceconfig::updateMainResponse(const QString &msg)
{
    if (mainWindow) {
        QTextEdit *responseTextEdit = mainWindow->findChild<QTextEdit*>("responseTextEdit");
        if (responseTextEdit) {
            responseTextEdit->append(msg);
            responseTextEdit->repaint();
        }
    }
}

void frmdeviceconfig::enableConfigControls(bool enable)
{
    ui->ntripIpLineEdit->setEnabled(enable);
    ui->ntripPortLineEdit->setEnabled(enable);
    ui->ntripMountPointLineEdit->setEnabled(enable);
    ui->ntripUsernameLineEdit->setEnabled(enable);
    ui->ntripPasswordLineEdit->setEnabled(enable);
    ui->sendConfigButton->setEnabled(enable);
    ui->cancelButton->setEnabled(enable);
}

void frmdeviceconfig::resetConfigFields()
{
    ui->ntripIpLineEdit->clear();
    ui->ntripPortLineEdit->clear();
    ui->ntripMountPointLineEdit->clear();
    ui->ntripUsernameLineEdit->clear();
    ui->ntripPasswordLineEdit->clear();
}

void frmdeviceconfig::onSerialDataReceived(const QString &data)
{
    if (isWaitingForNtripConfig) {
        parseNtripConfigResponse(data);
    }
}

void frmdeviceconfig::onTcpDataReceived(const QString &data)
{
    if (isWaitingForNtripConfig) {
        parseNtripConfigResponse(data);
    }
}

void frmdeviceconfig::parseNtripConfigResponse(const QString &data)
{
    if (!isWaitingForNtripConfig) {
        return;
    }

    // 验证是否为 NTRIP 配置响应
    if (!data.startsWith("$NTRIP,")) {
        return; // 不是 NTRIP 配置响应，忽略
    }

    // 解析响应
    QStringList parts = data.trimmed().split(",");
    if (parts.size() != 6) {
        updateMainResponse("错误：设备返回的 NTRIP 配置格式无效");
        isWaitingForNtripConfig = false;
        responseTimer.stop();
        return;
    }

    // 提取参数
    QString ip = parts[1].trimmed();
    QString port = parts[2].trimmed();
    QString mountPoint = parts[3].trimmed();
    QString username = parts[4].trimmed();
    QString password = parts[5].trimmed();

    // 验证参数
    if (ip.isEmpty() || mountPoint.isEmpty()) {
        updateMainResponse("错误：设备返回的 NTRIP IP 地址或挂载点为空");
        isWaitingForNtripConfig = false;
        responseTimer.stop();
        return;
    }

    bool ok;
    int portNum = port.toInt(&ok);
    if (!ok || portNum < 1 || portNum > 65535) {
        updateMainResponse("错误：设备返回的 NTRIP 端口号无效（必须为 1-65535 之间的整数）");
        isWaitingForNtripConfig = false;
        responseTimer.stop();
        return;
    }

    // 更新界面
    ui->ntripIpLineEdit->setText(ip);
    ui->ntripPortLineEdit->setText(port);
    ui->ntripMountPointLineEdit->setText(mountPoint);
    ui->ntripUsernameLineEdit->setText(username);
    ui->ntripPasswordLineEdit->setText(password);

    updateMainResponse("NTRIP 配置已从设备读取并更新到界面");
    isWaitingForNtripConfig = false;
    responseTimer.stop();
}

void frmdeviceconfig::onResponseTimeout()
{
    if (isWaitingForNtripConfig) {
        updateMainResponse("错误：设备未响应，查询超时");
        isWaitingForNtripConfig = false;
    }
}

void frmdeviceconfig::startResponseTimer()
{
    responseTimer.start(5000); // 5 秒超时
}